﻿package com.dg.gaming.api.common{
	import com.dg.gaming.api.common.msg.*;
	import nanoxml.XMLElement;
	public class User extends Observable implements ITransmittable {
		public static const XML_ATT_USERNAME:String="username";
		private static const XML_ATT_USERID:String="userid";
		private static const XML_ATT_RATING:String="rating";
		private static const XML_ATT_WINS:String="wins";
		private static const XML_ATT_LOSES:String="loses";
		private static const XML_ATT_DRAWS:String="draws";
		private static const XML_ATT_STREAK:String="streak";


		/** UserId of User. */
		protected var _userid:Number;

		/** Username of User. */
		protected var _username:String;

		/** Score rating of User. */
		protected var _rating:int=0;
		protected var _wins:int=0;
		protected var _draws:int=0;
		protected var _loses:int=0;
		protected var _streak:int=0;


		public function init(username:String,userid:Number,rating:int,wins:int,loses:int,draws:int,streak:int):void {
			this._username=username;
			this._userid=userid;
			this._rating=rating;
			this._wins=wins;
			this._loses=loses;
			this._draws=draws;
			this._streak=streak;
		}

		public function initXML(message:XMLElement):void {
			if (message.name!=Msg.USER) {
				throw new TransmissionException("Error parsing User");
			}
			this.init(message.getStringAttribute(XML_ATT_USERNAME),message.getLongAttribute(XML_ATT_USERID),message.getIntAttribute(XML_ATT_RATING),message.getIntAttribute(XML_ATT_WINS),message.getIntAttribute(XML_ATT_LOSES),message.getIntAttribute(XML_ATT_DRAWS),message.getIntAttribute(XML_ATT_STREAK));
		}
		/* INTERFACE com.dg.gaming.api.common.msg.ITransmittable */

		public function flatten():XMLElement {
			var message:XMLElement=new XMLElement  ;
			message.name=Msg.USER;
			message.setLongAttribute(XML_ATT_USERID,userid);
			message.setIntAttribute(XML_ATT_RATING,rating);
			message.setIntAttribute(XML_ATT_WINS,wins);
			message.setIntAttribute(XML_ATT_LOSES,loses);
			message.setIntAttribute(XML_ATT_DRAWS,draws);
			message.setIntAttribute(XML_ATT_STREAK,streak);
			return message;
		}

		public function get username():String {
			return _username;
		}

		public function set username(value:String):void {
			_username=value;
		}

		public function get userid():Number {
			return _userid;
		}

		public function set userid(value:Number):void {
			_userid=value;
		}

		public function get rating():int {
			return _rating;
		}

		public function set rating(value:int):void {
			_rating=value;
		}

		public function get wins():int {
			return _wins;
		}

		public function set wins(value:int):void {
			_wins=value;
		}

		public function get draws():int {
			return _draws;
		}

		public function set draws(value:int):void {
			_draws=value;
		}

		public function get loses():int {
			return _loses;
		}

		public function set loses(value:int):void {
			_loses=value;
		}

		public function get streak():int {
			return _streak;
		}

		public function set streak(value:int):void {
			_streak=value;
		}
		/**
		 * Return the number of games this player has played.
		 *
		 * @return   Total number of games played (wins + loses + draws).
		 */
		public function getGamesPlayed():int {
			return this.wins+this.loses+this.draws;
		}

		/**
		 * Return true if a user is still provisional.
		 *
		 * @return   True if user is still in provisional.
		 */
		public function isProvisional():Boolean {
			return getGamesPlayed()<IGame.PROVISIONAL_COUNT;
		}

		/**
		 * Update a user depending on a result type and their new rating.
		 *
		 * @param resultType  Result type - e.g. win, lose or draw
		 * @param newRating   New rating
		 */
		public function update(resultType:int,newRating:int):void {
			// Update wins/losses/draws depending on result type.
			switch (resultType) {
				case IGameOver.WIN :
					wins++;
					streak=streak>0?streak+1:1;
					break;
				case IGameOver.LOSE :
					loses++;
					streak=streak<0?streak-1:-1;
					break;
				case IGameOver.DRAW :
					draws++;
					streak=0;
					break;
			}

			// Update rating
			this.rating=newRating;

			// Update observers
			setChanged();
			notifyObservers();
		}
	}
}